home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / amiga.c next >
C/C++ Source or Header  |  1996-04-29  |  18KB  |  834 lines

  1. /* 
  2.  * UAE - The Un*x Amiga Emulator
  3.  *
  4.  * Amiga (native) specific support code; compiles with SAS/C 6.56,
  5.  * to get CyberGraphX support, add "DEFINE=_CYBERGFX" to the compiler
  6.  * flags in the smakefile. When running, hold down both Amiga keys
  7.  * to quit the emulation. The emulation also responds to ^C, which
  8.  * will abort it and to ^D which will reset it. Take care, the code
  9.  * appears to be very brittle and collapses easily if you switch
  10.  * screens. With CyberGraphX support enabled, the screen setup tries
  11.  * to be smart and falls back to standard screen update techniques
  12.  * if the screen to be opened does not belong to CyberGraphX. The
  13.  * 15/16/24 bit colour modes require that a graphics card like the
  14.  * CyberVision64 is installed that's not subject to byte ordering
  15.  * problems.
  16.  * 
  17.  * (c) 1996 Olaf `Olsen' Barthel
  18.  */
  19.  
  20. #include <intuition/intuitionbase.h>
  21. #include <intuition/pointerclass.h>
  22.  
  23. #include <graphics/gfxbase.h>
  24. #include <graphics/displayinfo.h>
  25.  
  26. #include <libraries/asl.h>
  27.  
  28. #include <exec/memory.h>
  29.  
  30. #include <dos/dos.h>
  31. #include <dos/dosasl.h>
  32.  
  33. #include <clib/intuition_protos.h>
  34. #include <clib/graphics_protos.h>
  35. #include <clib/exec_protos.h>
  36. #include <clib/dos_protos.h>
  37. #include <clib/asl_protos.h>
  38.  
  39. #include <pragmas/intuition_pragmas.h>
  40. #include <pragmas/graphics_pragmas.h>
  41. #include <pragmas/exec_pragmas.h>
  42. #include <pragmas/dos_pragmas.h>
  43. #include <pragmas/asl_pragmas.h>
  44.  
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <stdio.h>
  48.  
  49. #ifdef _CYBERGFX
  50. #include <cybergraphics/cybergraphics.h>
  51. #include <clib/cybergraphics_protos.h>
  52. #include <pragmas/cybergraphics_pragmas.h>
  53. #endif
  54.  
  55. /****************************************************************************/
  56.  
  57. #include "custom.h"
  58. #include "options.h"
  59. #include "keybuf.h"
  60. #include "filesys.h"
  61. #include "xwin.h"
  62.  
  63. /****************************************************************************/
  64.  
  65. extern struct ExecBase        *SysBase;
  66. extern struct DosLibrary    *DOSBase;
  67.  
  68. struct IntuitionBase    *IntuitionBase;
  69. struct GfxBase        *GfxBase;
  70. struct Library        *AslBase;
  71. struct Library        *CyberGfxBase;
  72.  
  73. /****************************************************************************/
  74.  
  75. STATIC struct Screen    *Screen;
  76. STATIC struct Window    *Window;
  77. STATIC Object        *Pointer;
  78. STATIC ULONG         WindowMask;
  79.  
  80. STATIC struct RastPort    *TempRPort,
  81.             *RenderPort;
  82. STATIC struct BitMap    *BitMap;
  83. STATIC UBYTE        *Line;
  84.  
  85. STATIC LONG         ScreenHeight,
  86.              ScreenWidth;
  87.  
  88. /****************************************************************************/
  89.  
  90. int buttonstate[3];
  91. int lastmx, lastmy;
  92. int newmousecounters;
  93. long int xcolors[4096];
  94. struct vidbuf_description gfxvidinfo;
  95.  
  96. /****************************************************************************/
  97.  
  98. void MC68000_reset(void);
  99.  
  100. /****************************************************************************/
  101.  
  102. STATIC VOID
  103. AmigaCleanup(VOID)
  104. {
  105.     if(BitMap)
  106.     {
  107.         WaitBlit();
  108.         FreeBitMap(BitMap);
  109.         BitMap = NULL;
  110.     }
  111.  
  112.     if(TempRPort)
  113.     {
  114.         FreeVec(TempRPort);
  115.         TempRPort = NULL;
  116.     }
  117.  
  118.     if(Line)
  119.     {
  120.         FreeVec(Line);
  121.         Line = NULL;
  122.     }
  123.  
  124.     if(Window)
  125.     {
  126.         CloseWindow(Window);
  127.         Window = NULL;
  128.     }
  129.  
  130.     if(Pointer)
  131.     {
  132.         DisposeObject(Pointer);
  133.         Pointer = NULL;
  134.     }
  135.  
  136.     if(Screen)
  137.     {
  138.         CloseScreen(Screen);
  139.         Screen = NULL;
  140.     }
  141.  
  142.     if(AslBase)
  143.     {
  144.         CloseLibrary(AslBase);
  145.         AslBase = NULL;
  146.     }
  147.  
  148.     if(GfxBase)
  149.     {
  150.         CloseLibrary(GfxBase);
  151.         GfxBase = NULL;
  152.     }
  153.  
  154.     if(IntuitionBase)
  155.     {
  156.         CloseLibrary(IntuitionBase);
  157.         IntuitionBase = NULL;
  158.     }
  159.  
  160.     if(CyberGfxBase)
  161.     {
  162.         CloseLibrary(CyberGfxBase);
  163.         CyberGfxBase = NULL;
  164.     }
  165. }
  166.  
  167. void
  168. flush_line(int y)
  169. {
  170.     if(!CyberGfxBase)
  171.     {
  172.         if(y >= 0 && y < ScreenHeight)
  173.         {
  174.             char *linebuf = y * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  175.  
  176.             CopyMem(linebuf,Line,ScreenWidth);
  177.             WritePixelLine8(RenderPort,0,y,ScreenWidth,Line,TempRPort);
  178.         }
  179.     }
  180. }
  181.  
  182. void
  183. flush_block(int ystart,int ystop)
  184. {
  185.     if(!CyberGfxBase)
  186.     {
  187.         if(ystart < 0)
  188.             ystart = 0;
  189.         else
  190.         {
  191.             if(ystart >= ScreenHeight)
  192.                 ystart = ScreenHeight - 1;
  193.         }
  194.  
  195.         if(ystop < 0)
  196.             ystop = 0;
  197.         else
  198.         {
  199.             if(ystop >= ScreenHeight)
  200.                 ystop = ScreenHeight - 1;
  201.         }
  202.  
  203.         if(ystart <= ystop)
  204.         {
  205.             char *mem;
  206.             int i;
  207.  
  208.             mem = ystart * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  209.  
  210.             for(i = ystart ; i <= ystop ; i++, mem += gfxvidinfo.rowbytes)
  211.             {
  212.                 CopyMem(mem,Line,ScreenWidth);
  213.                 WritePixelLine8(RenderPort,0,i,ScreenWidth,Line,TempRPort);
  214.             }
  215.         }
  216.     }
  217. }
  218.  
  219. void
  220. flush_screen(int ystart,int ystop)
  221. {
  222. }
  223.  
  224. static int
  225. get_color(int r,int g,int b,long *cnp)
  226. {
  227.     ULONG Red,Green,Blue;
  228.     LONG Pen;
  229.  
  230.     Red    = 0x11111111 * r;
  231.     Green    = 0x11111111 * g;
  232.     Blue    = 0x11111111 * b;
  233.  
  234.     Pen = ObtainBestPen(Screen->ViewPort.ColorMap,Red,Green,Blue,
  235.         OBP_Precision,PRECISION_IMAGE,
  236.     TAG_DONE);
  237.  
  238.     if(Pen == -1)
  239.         return(0);
  240.     else
  241.     {
  242.         *cnp = Pen;
  243.  
  244.         return(1);
  245.     }
  246. }
  247.  
  248. int
  249. graphics_init(void)
  250. {
  251.     struct ScreenModeRequester *ScreenRequest;
  252.     ULONG DisplayID;
  253.     struct BitMap PointerBitMap;
  254.     UWORD PointerLine;
  255.     struct DimensionInfo Dims;
  256.     BOOL GotOne;
  257.     LONG Depth;
  258.     int vsize;
  259.  
  260.     atexit(AmigaCleanup);
  261.  
  262.     vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
  263.  
  264.     if(!(gfxvidinfo.bufmem = malloc(800 * vsize)))
  265.     {
  266.         fprintf(stderr,"Sorry guv'nor, not enough memory for the line buffer.\n");
  267.         return(0);
  268.     }
  269.  
  270.     memset(gfxvidinfo.bufmem,0,800 * vsize);
  271.  
  272.     gfxvidinfo.rowbytes        = 800;
  273.     gfxvidinfo.pixbytes        = 1;
  274.     gfxvidinfo.maxblocklines    = 100;
  275.  
  276.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39)))
  277.     {
  278.         fprintf(stderr,"Sorry guv'nor, unable to open intuition.library v39.\n");
  279.         return(0);
  280.     }
  281.  
  282.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
  283.     {
  284.         fprintf(stderr,"Sorry guv'nor, unable to open graphics.library v39.\n");
  285.         return(0);
  286.     }
  287.  
  288.     DisplayID = INVALID_ID;
  289.     GotOne = FALSE;
  290.  
  291.     while((DisplayID = NextDisplayInfo(DisplayID)) != INVALID_ID)
  292.     {
  293.         if(GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID))
  294.         {
  295.             if(Dims.MaxDepth >= 8)
  296.             {
  297.                 GotOne = TRUE;
  298.                 break;
  299.             }
  300.         }
  301.     }
  302.  
  303.     if(!GotOne)
  304.     {
  305.         fprintf(stderr,"Sorry guv'nor, your Amiga needs an AA chip set or a graphics card.\n");
  306.         return(0);
  307.     }
  308.  
  309.     if(!(AslBase = OpenLibrary("asl.library",38)))
  310.     {
  311.         fprintf(stderr,"Sorry guv'nor, unable to open asl.library v38.\n");
  312.         return(0);
  313.     }
  314.  
  315.     if(!(ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL)))
  316.     {
  317.         fprintf(stderr,"Sorry guv'nor, unable to allocate screen mode requester.\n");
  318.         return(0);
  319.     }
  320.  
  321.     if(AslRequestTags(ScreenRequest,
  322.         ASLSM_TitleText,    "Select screen display mode",
  323.         ASLSM_MinDepth,        8,
  324.     TAG_DONE))
  325.     {
  326.         DisplayID = ScreenRequest->sm_DisplayID;
  327.  
  328.         GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID);
  329.  
  330.         Depth = Dims.MaxDepth;
  331.  
  332.         if(Depth > 8)
  333.             color_mode = 1;
  334.     }
  335.     else
  336.         DisplayID = INVALID_ID;
  337.  
  338.     FreeAslRequest(ScreenRequest);
  339.  
  340.     CloseLibrary(AslBase);
  341.     AslBase = NULL;
  342.  
  343.     if(DisplayID == INVALID_ID)
  344.         return(0);
  345.  
  346.     if(!(Screen = OpenScreenTags(NULL,
  347.         SA_DisplayID,    DisplayID,
  348.         SA_Depth,    Depth,
  349.         SA_Interleaved,    TRUE,
  350.         SA_ShowTitle,    FALSE,
  351.         SA_BackFill,    LAYERS_NOBACKFILL,
  352.         SA_Quiet,    TRUE,
  353.         SA_Behind,    TRUE,
  354.         SA_SharePens,    TRUE,
  355.         SA_Exclusive,    TRUE,
  356.         SA_Draggable,    FALSE,
  357.     TAG_DONE)))
  358.     {
  359.         fprintf(stderr,"Sorry guv'nor, unable to open the screen.\n");
  360.         return(0);
  361.     }
  362.  
  363.     ScreenWidth    = Screen->Width;
  364.     ScreenHeight    = Screen->Height;
  365.  
  366.     if(ScreenWidth > 800)
  367.         ScreenWidth = 800;
  368.  
  369.     if(ScreenHeight > 600)
  370.         ScreenHeight = 600;
  371.  
  372. #ifdef _CYBERGFX
  373.     if(CyberGfxBase = OpenLibrary("cybergraphics.library",40))
  374.     {
  375.         if(!IsCyberModeID(DisplayID) || ScreenHeight < vsize)
  376.         {
  377.             CloseLibrary(CyberGfxBase);
  378.             CyberGfxBase = NULL;
  379.         }
  380.     }
  381. #endif
  382.  
  383.     if(!(BitMap = AllocBitMap(Screen->Width,1,8,BMF_CLEAR|BMF_MINPLANES,Screen->RastPort.BitMap)))
  384.     {
  385.         fprintf(stderr,"Sorry guv'nor, unable to allocate BitMap.\n");
  386.         return(0);
  387.     }
  388.  
  389.     if(!(TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC)))
  390.     {
  391.         fprintf(stderr,"Sorry guv'nor, unable to allocate RastPort.\n");
  392.         return(0);
  393.     }
  394.  
  395.     if(!(Line = AllocVec((Screen->Width + 15) & ~15,MEMF_ANY|MEMF_PUBLIC)))
  396.     {
  397.         fprintf(stderr,"Sorry guv'nor, unable to allocate raster buffer.\n");
  398.         return(0);
  399.     }
  400.  
  401.     CopyMem(&Screen->RastPort,TempRPort,sizeof(struct RastPort));
  402.     TempRPort->Layer = NULL;
  403.     TempRPort->BitMap = BitMap;
  404.  
  405.     PointerLine = 0x0000;
  406.  
  407.     InitBitMap(&PointerBitMap,2,16,1);
  408.     PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine;
  409.     PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine;
  410.  
  411.     if(!(Pointer = NewObject(NULL,POINTERCLASS,
  412.         POINTERA_BitMap,    &PointerBitMap,
  413.         POINTERA_WordWidth,    1,
  414.     TAG_DONE)))
  415.     {
  416.         fprintf(stderr,"Sorry guv'nor, unable to allocate blank mouse pointer.\n");
  417.         return(0);
  418.     }
  419.  
  420.     if(!(Window = OpenWindowTags(NULL,
  421.         WA_Width,        Screen->Width,
  422.         WA_Height,        Screen->Height,
  423.         WA_CustomScreen,    Screen,
  424.         WA_Backdrop,        TRUE,
  425.         WA_Borderless,        TRUE,
  426.         WA_BackFill,        LAYERS_NOBACKFILL,
  427.         WA_RMBTrap,        TRUE,
  428.         WA_IDCMP,        IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
  429.         WA_Pointer,        Pointer,
  430.         WA_ReportMouse,        TRUE,
  431.     TAG_DONE)))
  432.     {
  433.         fprintf(stderr,"Sorry guv'nor, unable to open the window.\n");
  434.         return(0);
  435.     }
  436.  
  437.     RenderPort = &Screen->RastPort;
  438.  
  439.     WindowMask = 1UL << Window->UserPort->mp_SigBit;
  440.  
  441.     SetRast(RenderPort,0);
  442.  
  443.     switch(Depth)
  444.     {
  445.         case 8:
  446.  
  447.             alloc_colors256(get_color);
  448.             break;
  449.  
  450.         case 15:
  451.  
  452.             alloc_colors64k(5,5,5,10,5,0);
  453.             break;
  454.  
  455.         case 16:
  456.  
  457.             alloc_colors64k(5,6,5,11,5,0);
  458.             break;
  459.  
  460.         case 24:
  461.         case 32:
  462.  
  463.             alloc_colors64k(8,8,8,16,8,0);
  464.             break;
  465.     }
  466.  
  467.     ScreenToFront(Screen);
  468.     ActivateWindow(Window);
  469.  
  470.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  471.  
  472.     lastmx = lastmy = 0;
  473.     newmousecounters = 0;
  474.  
  475. #ifdef _CYBERGFX
  476.     if(CyberGfxBase)
  477.     {
  478.         free(gfxvidinfo.bufmem);
  479.  
  480.         gfxvidinfo.bufmem    = (char *)GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_DISPADR);
  481.         gfxvidinfo.rowbytes    = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_XMOD);
  482.         gfxvidinfo.pixbytes    = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_BPPIX);
  483.     }
  484. #endif
  485.     return(1);
  486. }
  487.  
  488. void
  489. graphics_leave(void)
  490. {
  491.     AmigaCleanup();
  492. }
  493.  
  494. void
  495. handle_events(void)
  496. {
  497.     ULONG Mask;
  498.  
  499.     Mask = SetSignal(0,SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|WindowMask);
  500.  
  501.     if(Mask & SIGBREAKF_CTRL_C)
  502.     {
  503.         PrintFault(ERROR_BREAK,"uae");
  504.         exit(RETURN_WARN);
  505.     }
  506.  
  507.     if(Mask & SIGBREAKF_CTRL_D)
  508.         MC68000_reset();
  509.  
  510.     if(Mask & WindowMask)
  511.     {
  512.         struct IntuiMessage *IMsg;
  513.         ULONG MsgClass;
  514.         UWORD MsgCode;
  515.         WORD MsgX,MsgY;
  516.         WORD Button;
  517.         BOOL Quit;
  518.  
  519.         newmousecounters = 0;
  520.         Quit = FALSE;
  521.  
  522.         while(IMsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
  523.         {
  524.             MsgClass    = IMsg->Class;
  525.             MsgCode        = IMsg->Code;
  526.             MsgX        = IMsg->MouseX;
  527.             MsgY        = IMsg->MouseY;
  528.  
  529.             if((IMsg->Qualifier & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) == (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
  530.                 Quit = TRUE;
  531.  
  532.             ReplyMsg(IMsg);
  533.  
  534.             switch(MsgClass)
  535.             {
  536.                 case IDCMP_RAWKEY:
  537.  
  538.                     if(MsgCode & IECODE_UP_PREFIX)
  539.                         record_key(((MsgCode & ~IECODE_UP_PREFIX) << 1) | 1);
  540.                     else
  541.                         record_key((MsgCode) << 1);
  542.  
  543.                     break;
  544.  
  545.                 case IDCMP_MOUSEBUTTONS:
  546.  
  547.                     switch(MsgCode & ~IECODE_UP_PREFIX)
  548.                     {
  549.                         case IECODE_LBUTTON:
  550.  
  551.                             Button = 0;
  552.                             break;
  553.  
  554.                         case IECODE_MBUTTON:
  555.  
  556.                             Button = 1;
  557.                             break;
  558.  
  559.                         case IECODE_RBUTTON:
  560.  
  561.                             Button = 2;
  562.                             break;
  563.                     }
  564.  
  565.                     if(MsgCode & IECODE_UP_PREFIX)
  566.                         buttonstate[Button] = 0;
  567.                     else
  568.                         buttonstate[Button] = 1;
  569.  
  570.                     break;
  571.  
  572.                 case IDCMP_MOUSEMOVE:
  573.  
  574.                     lastmx = MsgX;
  575.                     lastmy = MsgY;
  576.  
  577.                     newmousecounters = 1;
  578.  
  579.                     break;
  580.             }
  581.         }
  582.  
  583.         if(Quit)
  584.             exit(RETURN_OK);
  585.     }
  586. }
  587.  
  588. int
  589. debuggable(void)
  590. {
  591.     return 1;
  592. }
  593.  
  594. int
  595. needmousehack(void)
  596. {
  597.     return 1;
  598. }
  599.  
  600. void
  601. LED(int on)
  602. {
  603. }
  604.  
  605. /****************************************************************************/
  606.  
  607. int quit_program;
  608.  
  609. int
  610. gui_init(void)
  611. {
  612.     quit_program = 0;
  613. }
  614.  
  615. void
  616. gui_exit(void)
  617. {
  618. }
  619.  
  620. void
  621. gui_led(int led, int on)
  622. {
  623. }
  624.  
  625. void
  626. gui_filename(int num, char *name)
  627. {
  628. }
  629.  
  630. void
  631. gui_handle_events(void)
  632. {
  633. }
  634.  
  635. /****************************************************************************/
  636.  
  637. int    opterr = 1;            /* error => print message */
  638. int    optind = 1;            /* next argv[] index */
  639. char    *optarg = NULL;            /* option parameter if any */
  640.  
  641. static int
  642. Err( name, mess, c )            /* returns '?' */
  643.     char    *name;            /* program name argv[0] */
  644.     char    *mess;            /* specific message */
  645.     int    c;            /* defective option letter */
  646.     {
  647.     if ( opterr )
  648.         (void) fprintf( stderr,
  649.                 "%s: %s -- %c\n",
  650.                 name, mess, c
  651.                   );
  652.  
  653.     return '?';            /* erroneous-option marker */
  654.     }
  655.  
  656. int
  657. getopt( argc, argv, optstring )        /* returns letter, '?', EOF */
  658.     int        argc;        /* argument count from main */
  659.     char        *argv[];    /* argument vector from main */
  660.     char        *optstring;    /* allowed args, e.g. "ab:c" */
  661.     {
  662.     static int    sp = 1;        /* position within argument */
  663.     register int    osp;        /* saved `sp' for param test */
  664.     register int    c;        /* option letter */
  665.     register char    *cp;        /* -> option in `optstring' */
  666.  
  667.     optarg = NULL;
  668.  
  669.     if ( sp == 1 )            /* fresh argument */
  670.         if ( optind >= argc        /* no more arguments */
  671.           || argv[optind][0] != '-'    /* no more options */
  672.           || argv[optind][1] == '\0'    /* not option; stdin */
  673.            )
  674.             return EOF;
  675.         else if ( strcmp( argv[optind], "--" ) == 0 )
  676.             {
  677.             ++optind;    /* skip over "--" */
  678.             return EOF;    /* "--" marks end of options */
  679.             }
  680.  
  681.     c = argv[optind][sp];        /* option letter */
  682.     osp = sp++;            /* get ready for next letter */
  683.  
  684.     if ( argv[optind][sp] == '\0' )    /* end of argument */
  685.         {
  686.         ++optind;        /* get ready for next try */
  687.         sp = 1;            /* beginning of next argument */
  688.         }
  689.  
  690.     if ( c == ':'            /* optstring syntax conflict */
  691.       || (cp = strchr( optstring, c )) == NULL    /* not found */
  692.        )
  693.         return Err( argv[0], "illegal option", c );
  694.  
  695.     if ( cp[1] == ':' )        /* option takes parameter */
  696.         {
  697.         if ( osp != 1 )
  698.             return Err( argv[0],
  699.                     "option must not be clustered",
  700.                     c
  701.                   );
  702.  
  703.         if ( sp != 1 )        /* reset by end of argument */
  704.             return Err( argv[0],
  705.                    "option must be followed by white space",
  706.                     c
  707.                   );
  708.  
  709.         if ( optind >= argc )
  710.             return Err( argv[0],
  711.                     "option requires an argument",
  712.                     c
  713.                   );
  714.  
  715.         optarg = argv[optind];    /* make parameter available */
  716.         ++optind;        /* skip over parameter */
  717.         }
  718.  
  719.     return c;
  720.     }
  721.  
  722. /****************************************************************************/
  723.  
  724. static void usage(void)
  725. {
  726.     printf("UAE - The Un*x Amiga emulator\n");
  727.     printf("Summary of command-line options:\n");
  728.     printf("  -h                       : Print help\n");
  729.     printf("  -m VOLNAME:mount_point   : mount file system at <mount point> as AmigaDOS\n"
  730.        "                             volume VOLNAME:\n");
  731.     printf("  -M VOLNAME:mount_point   : like -m, but mount read-only\n");
  732.     printf("  -a                       : Don't mount the harddisk file automatically.\n"
  733.        "                             Useful only for testing.\n");
  734.     printf("  -S                       : Turn off sound support (if it is configured)\n");
  735.     printf("  -s                       : Emulate 1 MB slow memory at 0xC00000\n");
  736.     printf("  -F n                     : Emulate n MB fast memory at 0x200000\n");
  737.     printf("  -f n                     : Set the frame rate to 1/n\n");
  738.     printf("  -x                       : Use visible cross-hair cursor (X Windows version)\n");
  739.     printf("  -D                       : Start up the built-in debugger\n");
  740.     printf("  -[0123] file             : Use file instead of df[0123].adf as disk image file\n");
  741.     printf("  -r file                  : Use file as ROM image instead of kick.rom\n");
  742.     printf("  -J                       : Fake joystick emulation with the numeric pad.\n");
  743.     printf("  -g                       : Turn on gfx-lib replacement.\n");
  744.     printf("  -d mode                  : Select resolution with the mode parameter.\n");
  745.     printf("  -H mode                  : Set the number of colors with the mode parameter.\n");
  746.     printf("\n");
  747.     printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
  748.        "                   4 (800x600, correct aspect)\n"
  749.        "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
  750.        "UAE may choose to ignore the color mode/resolution setting.\n");
  751. }
  752.  
  753. void parse_cmdline(int argc, char **argv)
  754. {
  755. extern ULONG fastmem_size;
  756.  
  757.     int c;
  758.  
  759.     while(((c = getopt(argc, argv, "l:Df:gd:hxF:asSJm:M:0:1:2:3:r:H:")) != EOF)) switch(c) {
  760.      case 'h': usage();    exit(0);
  761.  
  762.      case '0': strncpy(df0, optarg, 255); df0[255] = 0;    break;
  763.      case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
  764.      case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
  765.      case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
  766.      case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
  767.  
  768.      case 'm':
  769.      case 'M':
  770.     {
  771.         /* mount file system (repeatable)
  772.          * syntax: [-m | -M] VOLNAME:/mount_point
  773.          * example: -M CDROM:/cdrom -m UNIXFS:./disk
  774.          */
  775.         static int mount_seen = 0;
  776.         char buf[256];
  777.         char *s2;
  778.         int readonly = (c == 'M');
  779.  
  780.         if (mount_seen)
  781.         fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
  782.         mount_seen = 1;
  783.         strncpy(buf, optarg, 255); buf[255] = 0;
  784.         s2 = strchr(buf, ':');
  785.         if(s2) {
  786.         *s2++ = '\0';
  787.         add_filesys_unit(buf, s2, readonly);
  788.         } else {
  789.         fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
  790.         }
  791.     }
  792.     break;
  793.  
  794.      case 'S': produce_sound = 0; break;
  795.      case 'f': framerate = atoi(optarg); break;
  796.      case 'x': use_xhair = 1; break;
  797.      case 'D': use_debugger = 1; break;
  798.      case 'J': fake_joystick = 1; break;
  799.      case 'a': automount_uaedev = 0; break;
  800.      case 's': use_slow_mem = 1; break;
  801.      case 'g': use_gfxlib = 1; break;
  802.  
  803.      case 'F':
  804.     fastmem_size = atoi(optarg) * 0x100000;
  805.     if (fastmem_size != 0x100000 && fastmem_size != 0x200000
  806.         && fastmem_size != 0x400000 && fastmem_size != 0x800000)
  807.     {
  808.         fastmem_size = 0;
  809.         fprintf(stderr, "Unsupported fastmem size!\n");
  810.     }
  811.  
  812.     break;
  813.  
  814.      case 'd':
  815.     screen_res = atoi(optarg);
  816.     if (screen_res >= 0 && screen_res <= 4) {
  817.     } else {
  818.         fprintf(stderr, "Bad video mode selected. Using default.\n");
  819.         screen_res = 3;
  820.     }
  821.     dont_want_aspect = screen_res != 4;
  822.     use_lores = screen_res < 3;
  823.     break;
  824.  
  825.      case 'H':
  826.     color_mode = atoi(optarg);
  827.     if (color_mode < 0 || color_mode > 2) {
  828.         fprintf(stderr, "Bad color mode selected. Using default.\n");
  829.         color_mode = 0;
  830.     }
  831.      break;
  832.     }
  833. }
  834.